筆記目錄

Skip to content

如何將 Vue 與 ASP.NET Razor 一起使用

TLDR

  • 在 ASP.NET Razor Pages 中整合 Vue 2,建議透過 _Layout.cshtml 統一初始化 Vue 實例,並利用 mixins 擴充各頁面的邏輯。
  • 為了避免「未編譯模板閃現」,務必使用 v-cloak 指令並配合 CSS 設定。
  • Vue 模板內禁止放置 <script> 標籤,否則會觸發編譯錯誤。
  • 在 Razor Pages 中使用 Vue 語法時,若遇到 @ 符號(如 @click),需使用 @@ 進行跳脫,且在 Tag Helper 屬性中應避免使用 Vue 的 @ 簡寫。
  • 處理 Ajax 請求時,需透過 axiosinterceptors 自動注入 RequestVerificationToken 以通過 Antiforgery 驗證。
  • 若需保留 ASP.NET 的 Model Validation,可透過自定義 TagHelper 將後端驗證屬性轉換為 VeeValidate 所需的 HTML 屬性。

Vue 與 Razor 的整合架構

在 ASP.NET Razor Pages 中整合 Vue,核心概念是將 Vue 的生命週期與 Razor 的頁面結構結合。建議將 Vue 實例的初始化放在 _Layout.cshtml,並利用 Vue 的 mixins 功能,讓各個頁面(.cshtml)能夠注入各自的資料與方法。

實作方式

  1. _Layout.cshtml 中定義一個全域的 mixins 陣列。
  2. 頁面透過 @section Scripts 將該頁面專屬的 pageMixin 推入 mixins 陣列。
  3. 最後在 _Layout.cshtml 底部統一執行 new Vue({ el: '#vueApp', mixins: mixins })

避免閃現問題

什麼情況下會遇到:頁面載入初期,瀏覽器尚未解析 Vue 模板,導致使用者看到原始的 語法。

  • 解決方案:在根元素加上 v-cloak,並在 CSS 中設定 [v-cloak] { display: none; }

整合注意事項

模板限制

什麼情況下會遇到:在 Vue 渲染的 DOM 範圍內直接撰寫 <script> 標籤。

  • 踩雷紀錄:Vue 模板僅負責 UI 映射,不允許包含具有副作用的標籤。
  • 建議做法:將所有 JavaScript 邏輯移至 @section Scripts 區塊中。

Razor 與 Vue 語法衝突

什麼情況下會遇到:在 Razor Pages 中使用 Vue 的 @ 簡寫(如 @click)。

  • 原因分析:@ 是 Razor 的保留字,且 Tag Helper 屬性對特殊字元有嚴格限制。
  • 建議做法:
    • 一般 HTML 屬性使用 @@click 跳脫。
    • 若該元素包含 asp-for 等 Tag Helper,應避免使用 @ 簡寫,改用 v-on:click 以確保編譯正確。

取代 jQuery 的替代方案

Ajax 與安全性

什麼情況下會遇到:使用 axios 發送 POST 請求時,因缺少 RequestVerificationToken 導致 400 Bad Request。

  • 建議做法:在 axiosinterceptors 中攔截請求,並從頁面隱藏欄位中讀取 Token 加入 Header:
javascript
axios.interceptors.request.use(
    config => {
        let token = document.querySelector('input[name="__RequestVerificationToken"]');
        if (token !== null) {
            config.headers = {
                RequestVerificationToken: token.value
            }
        }
        return config;
    },
    error => {
        return Promise.reject(error);
    }
);

前端驗證整合

什麼情況下會遇到:希望保留 ASP.NET 的 Validation Attributes(如 [Required]),同時在前端使用 VeeValidate 進行即時驗證。

  • 建議做法:建立自定義 TagHelper,自動將後端 Model 的驗證規則轉換為 v-validate 屬性。

VeeValidationInputTagHelper 範例: 此 TagHelper 會自動讀取 asp-for 的 Metadata,並產生對應的 v-validate 規則。

csharp
// 簡化版邏輯,將後端 Attribute 轉為 VeeValidate 規則
if (For.Metadata.ValidatorMetadata.Any(x => x is RequiredAttribute)) {
    output.Attributes.Add("v-validate", "'required'");
}

VeeValidationMessageTagHelper 範例: 用於顯示錯誤訊息:

csharp
public override void Process(TagHelperContext context, TagHelperOutput output) {
    output.Attributes.Add("v-show", $"errors.has('{For.Name}')");
    output.Content.SetHtmlContent($"{{{{ errors.first('{For.Name}') }}}}");
}

異動歷程

  • 2022-10-24 初版文件建立。